﻿using System;
using System.Collections.Generic;
using CookComputing.XmlRpc;
using PerceptiveMCAPI.Types;
//
namespace PerceptiveMCAPI.Methods
{
   public class campaignCreate : Api_BaseExecute
   {
      private new campaignCreateInput Input { get; set; }
      private campaignCreateOutput Output { get; set; }
      // =============================================== constructors
      public campaignCreate() { }
      // ---------
      public campaignCreate( campaignCreateInput input ) { Input = input; }
      // =============================================== Execute
      public campaignCreateOutput Execute()
      {
         // empty constructor & Execute() is bad
         if ( Input == null )
            throw new ArgumentException( "Input class not provided" );
         // do the deed
         Output = Execute( Input );
         return Output;
      }
      // ---------------------------------------------
      public campaignCreateOutput Execute( campaignCreateInput input )
      {
         Input = input;
         Output = new campaignCreateOutput( Input );
         ValidationIsOK = true;
         //-------------------------
         if ( Input.api_Validate )
         {
            Output.api_ValidatorMessages = ValidateInput.Validate( Input );
            ValidationIsOK = ValidateInput.IsOK( Output.api_ValidatorMessages );
         }
         //------------------------- do it
         if ( ValidationIsOK )
         {
            ApiRun( Input, input.parms.apikey );  // execute API & format output
         }
         // ---
         return Output;
      }

      #region ================================================================= API Calls

      // ---------------------------------------------------------- XmlRpc
      protected override void ExecuteXmlRpc()
      {
         try
         {
            // ---------------------------------- rpc format -------------------------------------------
            string type = Input.parms.type.ToString();
            XmlRpcStruct options = apiXmlRpc.FormatCampaignOptions( Input.parms.options );
            XmlRpcStruct content = apiXmlRpc.FormatDictionaryToXmlRpcStruct( (Dictionary<string, string>)Input.parms.content );
            XmlRpcStruct segOpts = apiXmlRpc.FormatSegmentOptions( Input.parms.segment_opts );
            XmlRpcStruct type_opts = apiXmlRpc.FormatDictionaryToXmlRpcStruct( (Dictionary<string, string>)Input.parms.type_opts );
            // ---------------------------------- rpc call -------------------------------------------
            string rpcResult = apiXmlRpc.api.campaignCreate(
               Input.parms.apikey, type, options, content, segOpts, type_opts );
            Output.Format( rpcResult );
         }
         catch ( XmlRpcFaultException fex )
         {
            Output.api_ErrorMessages.Add( apiException.FormatError( fex ) );
         }
         catch ( Exception ex )
         {
            Output.api_ErrorMessages.Add( apiException.FormatError( ex ) );
         }
      }
      // ---------------------------------------------------------- Serial Post
      protected override void ExecuteSerialPost()
      {
         try
         {
            Dictionary<string, string> dict = new Dictionary<string, string>();
            dict.Add( "apikey", Input.parms.apikey );
            dict.Add( "type", Input.parms.type.ToString() );
            // -----------
            // options
            // -----------
            dict.Add( "options[list_id]", Input.parms.options.list_id ?? "" );
            dict.Add( "options[subject]", Input.parms.options.subject ?? "" );
            dict.Add( "options[from_email]", Input.parms.options.from_email ?? "" );
            dict.Add( "options[from_name]", Input.parms.options.from_name ?? "" );
            dict.Add( "options[to_email]", Input.parms.options.to_email ?? "" );
            if ( Input.parms.options.template_id > 0 )
               dict.Add( "options[template_id]", Input.parms.options.template_id.ToString() );
            if ( Input.parms.options.folder_id > 0 )
               dict.Add( "options[folder_id]", Input.parms.options.folder_id.ToString() );
            dict.Add( "options[tracking][opens]", Input.parms.options.tracking.opens.ToString() );
            dict.Add( "options[tracking][html_clicks]", Input.parms.options.tracking.html_clicks.ToString() );
            dict.Add( "options[tracking][text_clicks]", Input.parms.options.tracking.text_clicks.ToString() );
            dict.Add( "options[title]", Input.parms.options.title );
            dict.Add( "options[authenticate]", Input.parms.options.authenticate.ToString() );
            foreach ( KeyValuePair<string, string> analytics in Input.parms.options.analytics )
            {
               dict.Add( string.Format( "options[analytics][{0}]", analytics.Key ), analytics.Value );
            }
            dict.Add( "options[auto_footer]", Input.parms.options.auto_footer.ToString() );
            dict.Add( "options[inline_css]", Input.parms.options.inline_css.ToString() );
            dict.Add( "options[generate_text]", Input.parms.options.generate_text.ToString() );
            dict.Add( "options[auto_tweet]", Input.parms.options.auto_tweet.ToString() );
            dict.Add( "options[timewarp]", Input.parms.options.timewarp.ToString() );
            dict.Add( "options[ecomm360]", Input.parms.options.ecomm360.ToString() );
            // -------------
            // segment_opts
            // -------------
            if ( Input.parms.segment_opts != null && Input.parms.segment_opts.conditions.Count > 0 )
            {
               dict.Add( "segment_opts[match]", Input.parms.segment_opts.match );
               List<campaignSegmentCondition> conds = Input.parms.segment_opts.conditions;
               int i = -1;
               foreach ( campaignSegmentCondition cond in conds )
               {
                  i++;
                  dict.Add( string.Format( "segment_opts[conditions][{0}][field]", i ), cond.field ?? "" );
                  dict.Add( string.Format( "segment_opts[conditions][{0}][op]", i ), cond.op ?? "" );
                  dict.Add( string.Format( "segment_opts[conditions][{0}][value]", i ), cond.value ?? "" );
                  if ( !string.IsNullOrEmpty( cond.extra ) )
                     dict.Add( string.Format( "segment_opts[conditions][{0}][extra]", i ), cond.extra );
               }
            }
            // ----------------------------------  
            // type_opts
            // ----------------------------------  
            foreach ( KeyValuePair<string, string> type_opts in Input.parms.type_opts )
            {
               dict.Add( string.Format( "type_opts[{0}]", type_opts.Key ), type_opts.Value ?? "" );
            }
            // ----------------------------------  
            // content
            // ----------------------------------  
            foreach ( KeyValuePair<string, string> contentEntry in Input.parms.content )
            {
               dict.Add( string.Format( "content[{0}]", contentEntry.Key ), contentEntry.Value ?? "" );
            }
            // -- do it
            string api_Request = "";
            string api_Response = apiSerial.ProcessRequest( Input, dict, out api_Request );
            Output.Format( api_Request, api_Response );
         }
         catch ( Exception ex )
         {
            Output.api_ErrorMessages.Add( apiException.FormatError( ex ) );
         }
      }

      #endregion
   }
}
